Base.namespace('Base.mobile');

Base.mobile.selectedFeature = null;
Base.mobile.map = null;
Base.mobile.ui  = null;

/**
 * Class: Base.mobile.Ui
 * @class 
 */
Base.mobile.UiStatic = {

    vote_types_url : "/cc/vote/types/",
    vote_url       : "/cc/vote/",
    vote_images    : "images/ui/vote/",

    all_votes_url  : null,
    all_votes_data : null,
    active_vote_type : 1,

    map     : null,
    mapctl  : null,
    types   : null,
    confirmed : false, // controls the annoying 'confirm' dialog (shuts it off after first vote)
    vcount    : 0,     // counts how many times this user votes


    /** */
    initialize : function(config)
    {
        if(Base.isLocalHost())
        {
            this.vote_types_url = "test/vote_types.json";
            this.vote_url       = "test/vote.json";
            this.all_votes_url  = "test/votes_all.json";
        }
        Base.configure(this, config);

        if(this.all_votes_url == null) 
            this.all_votes_url = this.vote_url;

        if(this.types == null) {
            $.ajax({
                url: this.vote_types_url,
                dataType: "json",
                context: this,
                success: function(data, textStatus, jqXHR){
                    this.types = data.types;
                }
            });
        }

        // global OL map & ui pointers (needed for callbacks below) 
        Base.mobile.map = this.map;
        Base.mobile.ui  = this;

        $(window).bind("orientationchange resize pageshow", this.fixContentHeight);
        this.fixContentHeight(); 
        this.buttons();
        $('div#popup').live('pageshow', this.popup);
        this.layers();
        this.mapctl.addSelectControl(this.select);
    },

    /** */
    select : function(feature)
    {
        Base.mobile.selectedFeature = feature; 
        $.mobile.changePage($("#popup"), "pop"); 
    },

    /** */
    refreshAllVotesData : function()
    {
        $.ajax({
            url: this.all_votes_url + '?time=' + new Date().getTime(),
            dataType: "json",
            context: this,
            success: function(data, textStatus, jqXHR){
                this.all_votes_data = data.averages;
            }
        });
    },

    /** find a vote from the vote data */
    getVote : function(id, type)
    {
        var retVal = null;
        if(this.all_votes_data)
        {
            if(type == null)
                type = this.active_vote_type;
            
            for(var i in this.all_votes_data)
            {
                var vid   = this.all_votes_data[i].feature; 
                var vtype = this.all_votes_data[i].type;
                if(vid == id && vtype == type) {
                    retVal = this.all_votes_data[i];
                    break;
                } 
            }
        }
        return retVal;
    },

    /** zoom buttons, etc... */
    buttons : function()
    {
        var THIS = this;
        $("#plus").click(function(){
            THIS.map.zoomIn();
        });
        $("#minus").click(function(){
            THIS.map.zoomOut();
        });
        $("#locate").click(function(){
            var control = THIS.map.getControlsBy("id", "locate-control")[0];
            if (control.active) {
                control.getCurrentLocation();
            } else {
                control.activate();
            }
        });
    },

    /** convert all feature attributes to list items */
    attributesToItems : function(attributes)
    {
        //
        // IMPORTANT NOTE about STYLE attribute below
        // Need that -- can't use CSS to do this reliably (at least I couldn't) get CSS to work properly -- see .opt-left & .opt-right in style.mobile.css
        // Also, 30% / 70% is proper spacing on smaller screens for the left side content
        //
        var li = "";
        for(var attr in attributes){
            li += '<li>'
               +  '<div style="width:30%;float:left">'  + attr + '</div>'
               +  '<div style="width:70%;float:right">' + attributes[attr] + '</div>'
               +  '</li>'; 
        }
        return li;
    },

    /** convert all feature attributes to list items */
    streetAndModeAttributesToItems : function(attributes)
    {
        //
        // IMPORTANT NOTE about STYLE attribute below
        // Need that -- can't use CSS to do this reliably (at least I couldn't) get CSS to work properly (see .opt-left & .opt-right in style.mobile.css)
        // Also, 30% / 70% is proper spacing on smaller screens for the left side content
        //
        var name = "";
        if(attributes.prefix) name += attributes.prefix + " ";
        if(attributes.name)   name += attributes.name;
        if(attributes.type)   name += " " + attributes.type;

        var li = "";
            li += '<li>'
               +  '<div style="width:30%;float:left">'  + 'Name' + '</div>'
               +  '<div style="width:70%;float:right">' +  name  + '</div>'
               +  '</li>'; 

            li += '<li>'
               +  '<div style="width:30%;float:left">'  + 'Type' + '</div>'
               +  '<div style="width:70%;float:right">' + attributes.mode + '</div>'
               +  '</li>'; 

        return li;
    },


    /**
     *  vote popup callback
     *  will build a list of content to show in the popup 
     *  NOTE: 'this' pointer scope is in jQuery, hence the use of global pointers to ui and feature.
     */
    popup : function(event, prevPage)
    {
        var ui = Base.mobile.ui;
        var feature = Base.mobile.selectedFeature;

        var vote_id = "vote-";
        var tot_id  = "total-";
        var desc_id = "description-";


        // step 1: show the feature name and street type (mode) in the first two rows (data comes from WFS select call)
        var li = ui.streetAndModeAttributesToItems(feature.attributes);
 

        // step 2: add 'vote' rows HTML for all the vote_types that are currently showing...
        var types = ui.types;
        if(types)
        for(var i=0; i < types.length; i++)
        {
            // only show vote types that are turned on
            if(types[i].display != "1")
                continue; 

            var vid = vote_id + types[i].id;
            var did = desc_id + types[i].id;
            var tot = tot_id  + types[i].id;

            li += '<li>'
               +  '<div style="width:30%;float:left" title="' + types[i].description + '">'  + types[i].name + '<div id="' + tot + '" class="total">No votes yet</div></div>'
               +  '<div style="width:70%;float:right">' + '<div id="' + vid + '" class="left" vote_type="' + types[i].id + '"></div><div id="' + did + '" class="raty-target"></div></div>';
               +  '<li>';
        }

        // step 3: add a dummy row at the bottom, so that the bottom vote row doesn't get cut off
        li += '<li>'
           +  '<div style="width:30%;float:left">'  + 'CrowdCycle' + '</div>'
           +  '<div style="width:70%;float:right">' + 'Beta' + '</div>'
           +  '</li>'; 


        // step 4: add list html to the DOM
        $("ul#details-list").empty().append(li).listview("refresh");


        // step 5: add the jquery raty magic to the vote rows added above in step 2;
        //         create votes with null averages (no stars) initially.
        if(types)
        for(var i=0; i < types.length; i++) 
        {
            // only show vote types that are turned on
            if(types[i].display != "1")
                continue; 

            var vid = '#' + vote_id + types[i].id;
            var did = '#' + desc_id + types[i].id;
            var hints = [types[i].value_1, types[i].value_2, types[i].value_3, types[i].value_4, types[i].value_5];

            $(vid).raty({
                cancel: true,
                path: ui.vote_images,
                cancelHint: 'none',
                hintList: hints,
                target: did,
                vote_type: types[i].id,
                prev_value: 0,
                start: null,
                click: function(score, evt) {
                    /* 
                     * VOTE click call back (when someone clicks on a vote
                     */ 
                    if(score == null)
                        score = 0;

                    // remind the user every so often that they're submitting votes with every click.
                    if(ui.confirmed == false || ui.vcount % 5 == 0)
                        ui.confirmed = confirm("Submit your vote of " + score + " stars?");

                    if(ui.confirmed == true)
                    {
                        ui.vcount++;
                        var vt = this.selector.substring(this.selector.length-1); 
                        var url = ui.vote_url + '?feature=' + feature.attributes.street_id + '&type=' + vt + '&vote=' + score + '&time=' + new Date().getTime();
                        $.ajax({
                            url: url,
                            dataType: "json",
                            context: this,
                            success: function(data, textStatus, jqXHR){
                               /* 
                                * VOTE submit call back (when someone places a vote, and it gets sent to the server)
                                */ 
                                console.log("success sumbitting the vote");
                                // TODO: calculate new vote information (or call the vote service, or return updated vote info in the OK message).
                            }
                        });
                    }
                    else
                    {
                        // TODO : when user declines to vote, then revert back to old vote information (stars back to normal)
                        //var pv = $(this.selector)["prev_vote"];
                        //alert(pv);
                    }
                }
            }); // end of $(vid).raty({
        } // end for loop


        // step 6: make call to vote service to get actual votes for this feature, and adjust the blank vote information with that from db
        var cfg = {
            url: ui.vote_url + "?feature=" + feature.attributes.street_id + '&time=' + new Date().getTime(),
            dataType: "json",
            context: this,
            success: function(data, textStatus, jqXHR, x, y){
                var start = null;
                if (data && data.averages)
                for(var i in data.averages)
                {
                    var vid = '#' + vote_id + data.averages[i].type;
                    var tot = '#' + tot_id  + data.averages[i].type;

                    var avg = data.averages[i].avg;
                    $(vid)["prev_vote"] = avg;
                    $.fn.raty.start(avg, vid);
                    $(tot).empty().append(data.averages[i].num + " votes")
                }
            }
        };
        $.ajax(cfg);
    },

    /** fix height of map content area */
    fixContentHeight : function()
    {
        var footer = $("div[data-role='footer']:visible");
        var content = $("div[data-role='content']:visible:visible");
        var viewHeight = $(window).height();
        var contentHeight = viewHeight - footer.outerHeight();

        if ((content.outerHeight() + footer.outerHeight()) !== viewHeight) {
            contentHeight -= (content.outerHeight() - content.height());
            content.height(contentHeight);
        }

        var map = this.map;
        if(map == null)
            map = Base.mobile.map;
        if(map)
            map.updateSize();
    },

    /** add map layers to the button */
    layers : function()
    {
        var THIS = this;
        $('#layerslist').listview();
        $('<li>', {
                "data-role": "list-divider",
                text: "Base Layers"
            })
            .appendTo('#layerslist');
        var baseLayers = this.map.getLayersBy("isBaseLayer", true);
        $.each(baseLayers, function() {
            THIS.addLayerToList(this);
        });
    
        $('<li>', {
                "data-role": "list-divider",
                text: "Overlay Layers"
            })
            .appendTo('#layerslist');
        var overlayLayers = this.map.getLayersBy("isBaseLayer", false);
        $.each(overlayLayers, function() {
            THIS.addLayerToList(this);
        });
        $('#layerslist').listview('refresh');

        //keep this commented out so events don't appear in the layers list -- probably only here for debugging purposes
		/*this.map.events.register("addlayer", this, function(e) {
            THIS.addLayerToList(e.layer);
        });*/
    },

    addLayerToList : function(layer)
    {
        var item = $('<li>', {
                "data-icon": "check",
                "class": layer.visibility ? "checked" : ""
            })
            .append($('<a />', {
                text: layer.name
            })
                .click(function() {
                    $.mobile.changePage('mappage');
                    if (layer.isBaseLayer) {
                        layer.map.setBaseLayer(layer);
                    } else {
                        layer.setVisibility(!layer.getVisibility());
                    }
                })
            ) // end .append
            .appendTo('#layerslist');

        layer.events.on({
            'visibilitychanged': function() {
                $(item).toggleClass('checked');
            }
        });
    },

    CLASS_NAME: "Base.mobile.Ui"
}
Base.mobile.Ui = new Base.Class(Base.mobile.UiStatic);
